package com.chenxin.wms.process.outbound.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.chenxin.common.constant.WmsConstants;
import com.chenxin.common.core.domain.ProcResult;
import com.chenxin.common.enums.WmsBusinessStatus;
import com.chenxin.common.enums.WmsTaskSubType;
import com.chenxin.common.enums.WmsTaskType;
import com.chenxin.common.exception.wms.WmsException;
import com.chenxin.common.utils.StringUtils;
import com.chenxin.wms.domain.ObDetailEntity;
import com.chenxin.wms.domain.StockEntity;
import com.chenxin.wms.domain.TaskEntity;
import com.chenxin.wms.domain.dto.ManualAllotRequestDTO;
import com.chenxin.wms.domain.po.LocationInfo;
import com.chenxin.wms.domain.po.ObDetailInfo;
import com.chenxin.wms.mapper.LocationMapper;
import com.chenxin.wms.mapper.ObDetailMapper;
import com.chenxin.wms.mapper.StockMapper;
import com.chenxin.wms.process.outbound.IProcManualAllotByDetail;
import com.chenxin.wms.process.task.ITaskProcess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class ProcManualAllotByDetail implements IProcManualAllotByDetail {
    @Autowired
    private ObDetailMapper obDetailMapper;
    @Autowired
    private StockMapper stockMapper;
    @Autowired
    private LocationMapper locationMapper;
    @Autowired
    private ITaskProcess taskProcess;

    @Override
    public ProcResult call(Long obDetailId, List<ManualAllotRequestDTO.StockInfo> stocks, Long creator) {
        if (StringUtils.isNull(obDetailId)) {
            return ProcResult.error("manual_allot_err001", "手动备货的明细ID不能为空！");
        }
        if (StringUtils.isEmpty(stocks)) {
            return ProcResult.error("manual_allot_err002", "手动备货所选库存信息不能为空！");
        }
        // 通过ID获取对应详情
        ObDetailInfo obDetailInfo = obDetailMapper.selectObDetailInfoById(obDetailId);
        if (obDetailInfo == null) {
            return ProcResult.error("manual_allot_err003", "手动备货的明细ID[" + obDetailId + "]不存在");
        }
        if (obDetailInfo.getObDetailStatus() > WmsBusinessStatus.OB_MASTER_PREPARING.getCode()) {
            return ProcResult.error("manual_allot_err004", "手动备货的明细ID【" + obDetailId + "】当前状态【" + obDetailInfo.getObDetailStatus() + "】无法执行手动备货");
        }
        // 确认一下单据已绑定数量（还需要绑多少）
        BigDecimal remainBindQty = obDetailInfo.getObPlanQty().subtract(obDetailInfo.getObBindQty());
        // 对手动选取的库存进行处理
        for (ManualAllotRequestDTO.StockInfo selectStock : stocks) {
            // 判断此次手动备货数量是否超配
            if (remainBindQty.compareTo(selectStock.getAllotQty()) < 0) {
                return ProcResult.error("manual_allot_err008", "所选库存ID【" + selectStock.getStockId() + "】累计备货数量【" + selectStock.getAllotQty() + "】超出明细ID【" + obDetailId + "】需求数量!");
            }
            remainBindQty = remainBindQty.subtract(selectStock.getAllotQty());
            // 判断库存是否存在
            StockEntity stock = stockMapper.selectById(selectStock.getStockId());
            if (stock == null) {
                throw new WmsException("manual_allot_err005", "所选库存ID【" + selectStock.getStockId() + "】不存在，明细ID【" + obDetailId + "】");
            }
            // 手动分配的数量不能大于该调库存可用数量
            BigDecimal reqQty = selectStock.getAllotQty();
            BigDecimal usableQty = stock.getStockQty().subtract(stock.getLockedQty());
            if (reqQty.compareTo(usableQty) > 0) {
                throw new WmsException("manual_allot_err006", "所选库存ID【" + selectStock.getStockId() + "】手动分配【" + reqQty + "】，可用数量【" + usableQty + "】不足，明细ID【" + obDetailId + "】");
            }
            // 判断一下当前库存所在位置（不在货位上的库存不允许使用）
            LocationInfo locationInfo = locationMapper.selectLocationByNo(stock.getLocationNo());
            if (WmsConstants.LOCATION_TYPE_ST.equals(locationInfo.getLocationType())) {
                throw new WmsException("manual_allot_err007", "所选库存ID【" + selectStock.getStockId() + "】所在位置【" + stock.getLocationNo() + "】不能用于备货");
            }
            // 单据与所选库存都可用开始备货
            UpdateWrapper<StockEntity> stockUW = new UpdateWrapper<>();
            stockUW.lambda().eq(StockEntity::getStockId, stock.getStockId())
                    .set(StockEntity::getLockedQty, stock.getLockedQty().add(reqQty))
                    .set(StockEntity::getStockStatus, WmsConstants.STOCK_STATUS_PRE)
                    .set(StockEntity::getUpdater, creator)
                    .set(StockEntity::getUpdateDate, new Date());
            int updateRows = stockMapper.update(stock, stockUW);
            if (updateRows == 0) {
                throw new WmsException("manual_allot_err008", "所选库存ID【" + selectStock.getStockId() + "】更新失败，请稍后再试");
            }

            // 生成任务
            TaskEntity taskByManual = new TaskEntity();
            taskByManual.setTaskType(WmsTaskType.SHIPMENT_OUT.getCode());
            taskByManual.setTaskSubType(WmsTaskSubType.PREPARE_OUT.getCode());
            taskByManual.setFromContNo(stock.getContNo());
            taskByManual.setFromPosition(stock.getLocationNo());
            // 备货时目标位置暂不填写
            taskByManual.setToPosition("");
            taskByManual.setCurPosition(stock.getLocationNo());
            taskByManual.setSpuNo(stock.getSpuNo());
            taskByManual.setLotNo(stock.getLotNo());
            taskByManual.setPlanQty(reqQty);
            taskByManual.setActualQty(BigDecimal.ZERO);
            taskByManual.setMasterNo(obDetailInfo.getObMasterNo());
            taskByManual.setMasterId(obDetailInfo.getObMasterId());
            taskByManual.setDetailId(obDetailId);
            taskByManual.setStockId(stock.getStockId());
            taskByManual.setComments("手动备货成功");
            taskByManual.setCreator(creator);
            taskByManual.setCreateDate(new Date());
            ProcResult result = taskProcess.procWmsTaskInsert(taskByManual);
            if (!WmsConstants.PROC_SUCCESS.equals(result.getCode())) {
                throw new WmsException("manual_allot_err009", "生成任务失败,causeBy:" + result.getMessage());
            }
        }
        UpdateWrapper<ObDetailEntity> obDetailUw = new UpdateWrapper<>();
        obDetailUw.lambda().eq(ObDetailEntity::getObDetailId, obDetailId)
                .eq(ObDetailEntity::getVersion, obDetailInfo.getVersion())
                .set(ObDetailEntity::getVersion, obDetailInfo.getVersion() + 1)
                .set(ObDetailEntity::getObDetailStatus, remainBindQty.compareTo(BigDecimal.ZERO) > 0 ? WmsBusinessStatus.OB_DETAIL_PREPARING.getCode() : WmsBusinessStatus.OB_DETAIL_PREPARED.getCode())
                .set(ObDetailEntity::getUpdater, creator)
                .set(ObDetailEntity::getUpdateDate, new Date());
        int statusRows = obDetailMapper.update(obDetailUw);
        if (statusRows == 0) {
            throw new WmsException("prepare_err009", "更新明细【" + obDetailId + "】状态失败！");
        }
        return ProcResult.success("出库明细【" + obDetailId + "】手动备货成功!所属出库主单【" + obDetailInfo.getObMasterId() + "】");
    }
}
